﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using VulnDBExplorer.Services;
using Luna;
using System.Threading;

namespace VulnDBExplorer.Forms
{
	public partial class TaskProgressMonitor : UserControl, IProgressMonitor
	{
		private Thread callThread;

		public TaskProgressMonitor() {
			InitializeComponent();
			Enabled = false;

			this.lblTitle.Text = "";
			this.lblDescription.Text = "";

			btnStop.Click += (o, a) => cancel();
		}

		public IAppContext Context { get; set; }

		public event EventHandler Started;

		public event EventHandler Stopped;

		public event EventHandler Updated;

		protected void OnUpdated() {
			if (Updated != null) Updated(this, EventArgs.Empty);
		}

		#region IProgressMonitor Members

		public int Value {
			get {
				return bar.Value;
			}
			set {
				if (InvokeRequired)
					Invoke(new Action<int>(o => Value = o), value);
				else {
					bar.Value = value > bar.Maximum ? bar.Maximum : value;
					Update();
					OnUpdated();
				}
			}
		}

		public int Total {
			get {
				return bar.Maximum;
			}
			set {
				if (InvokeRequired)
					Invoke(new Action<int>(o => Total = o), value);
				else {
					bar.Maximum = value;
					bar.Style = value == int.MaxValue ? ProgressBarStyle.Marquee : ProgressBarStyle.Continuous;
					OnUpdated();
				}
			}
		}

		public bool Canceled { get; set; }

		public string Title {
			get {
				return lblTitle.Text;
			}
			set {
				if (InvokeRequired)
					Invoke(new Action<string>(o => Title = o), value);
				else {
					lblTitle.Text = value;
					Update();
					OnUpdated();
				}
			}
		}

		public string Description {
			get { return lblDescription.Text; }
			set {
				if (InvokeRequired)
					Invoke(new Action<String>(o => lblDescription.Text = o), value);
				else {
					lblDescription.Text = value;
					Update();
					OnUpdated();
				}
			}
		}

		public IProgressMonitor ParentTask { get; set; }

		public void start(string title, int maximum) {
			if (callThread == null) callThread = Thread.CurrentThread;
			if (InvokeRequired)
				Invoke(new Action<string, int>(start), title, maximum);
			else {
				Title = title;
				Value = 0;
				Total = maximum;
				Description = "";
				Enabled = true;
				if (Started != null) Started(this, EventArgs.Empty);
			}
		}

		public void stop() {
			if (InvokeRequired)
				Invoke(new Action(stop));
			else
				if (Stopped != null) Stopped(this, EventArgs.Empty);
		}

		public void update(int value, int total) {
			if (InvokeRequired)
				Invoke(new Action<int, int>(update), value, total);
			else {
				if (bar.Maximum != total) {
					bar.Maximum = total;
					bar.Style = total == int.MaxValue ? ProgressBarStyle.Marquee : ProgressBarStyle.Continuous;
				}
				if (bar.Value != value) bar.Value = Math.Min(value, bar.Maximum);
				OnUpdated();
			}
		}

		public void cancel() {
			callThread.Abort();
		}

		#endregion
	}
}
